import { NextRequest, NextResponse } from 'next/server';
import { AskRequest, AskResponse } from '@/types';
import { initializeDatabase, createSession, createMessage, createExecutionTrace, getSession } from '@/lib/database';
import { withCors } from '@/lib/cors';

// Flowise 配置
const FLOWISE_API_URL = process.env.FLOWISE_API_URL || 'http://localhost:3001';
const FLOWISE_API_KEY = process.env.FLOWISE_API_KEY;

// 初始化数据库
let dbInitialized = false;
async function ensureDatabaseInitialized() {
  if (!dbInitialized) {
    await initializeDatabase();
    dbInitialized = true;
  }
}

async function handlePOST(request: NextRequest) {
  try {
    await ensureDatabaseInitialized();
    
    const body: AskRequest = await request.json();
    
    // 验证必要参数
    if (!body.chatflowId || !body.question) {
      return NextResponse.json(
        { error: '缺少必要参数: chatflowId 和 question' },
        { status: 400 }
      );
    }

    // 生成会话 ID
    const sessionId = body.sessionId || `session_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
    
    // 检查会话是否存在，如果不存在则创建
    let session = await getSession(sessionId);
    if (!session) {
      await createSession({
        id: sessionId,
        chatflowId: body.chatflowId,
        userId: body.userId,
        startTime: new Date().toISOString(),
        messageCount: 0,
        status: 'active'
      });
    }
    
    // 保存用户消息到数据库
    await createMessage({
      id: `msg_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
      sessionId,
      role: 'user',
      content: body.question,
      timestamp: new Date().toISOString()
    });

    // 构建 Flowise 请求
    const flowiseRequest = {
      question: body.question,
      overrideConfig: {
        ...body.overrideConfig,
        // 添加会话 ID 到配置中
        sessionId: sessionId,
      },
    };

    // 准备请求头
    const headers: Record<string, string> = {
      'Content-Type': 'application/json',
    };

    if (FLOWISE_API_KEY) {
      headers['Authorization'] = `Bearer ${FLOWISE_API_KEY}`;
    }

    // 调用 Flowise API
    const flowiseResponse = await fetch(
      `${FLOWISE_API_URL}/api/v1/prediction/${body.chatflowId}`,
      {
        method: 'POST',
        headers,
        body: JSON.stringify(flowiseRequest),
      }
    );

    if (!flowiseResponse.ok) {
      const errorText = await flowiseResponse.text();
      console.error('Flowise API 错误:', errorText);
      return NextResponse.json(
        { error: 'Flowise API 调用失败', details: errorText },
        { status: flowiseResponse.status }
      );
    }

    const flowiseData = await flowiseResponse.json();
    const answer = flowiseData.answer || flowiseData.text || '抱歉，我无法回答这个问题。';
    const executionTrace = extractExecutionTrace(flowiseData);

    // 保存助手回复到数据库
    await createMessage({
      id: `msg_${Date.now() + 1}_${Math.random().toString(36).substr(2, 9)}`,
      sessionId,
      role: 'assistant',
      content: answer,
      timestamp: new Date().toISOString(),
      metadata: { flowiseData }
    });

    // 保存执行追踪到数据库
    for (let i = 0; i < executionTrace.length; i++) {
      const step = executionTrace[i];
      await createExecutionTrace({
        id: `trace_${Date.now() + i}_${Math.random().toString(36).substr(2, 9)}`,
        sessionId,
        stepName: step.nodeName || `步骤 ${i + 1}`,
        stepType: step.agentName || 'unknown',
        inputData: step.input,
        outputData: step.output,
        status: 'completed',
        timestamp: step.timestamp || new Date().toISOString()
      });
    }

    // 处理响应数据
    const response: AskResponse = {
      answer,
      executionTrace,
      chatMessages: [
        {
          role: 'user',
          content: body.question,
        },
        {
          role: 'assistant',
          content: answer,
        },
      ],
      sessionId,
    };

    return NextResponse.json(response);

  } catch (error) {
    console.error('API 错误:', error);
    return NextResponse.json(
      { error: '服务器内部错误', details: error instanceof Error ? error.message : '未知错误' },
      { status: 500 }
    );
  }
}

// 从 Flowise 响应中提取执行追踪信息
function extractExecutionTrace(flowiseData: any): any[] {
  const trace: any[] = [];

  // 尝试从不同字段提取追踪信息
  if (flowiseData.agentReasoning) {
    trace.push({
      agentName: 'Agent',
      nodeName: '推理过程',
      input: flowiseData.question || '',
      output: flowiseData.agentReasoning,
      timestamp: new Date().toISOString(),
    });
  }

  if (flowiseData.usedTools && Array.isArray(flowiseData.usedTools)) {
    flowiseData.usedTools.forEach((tool: any, index: number) => {
      trace.push({
        agentName: 'Tool Agent',
        nodeName: `工具调用 ${index + 1}`,
        input: tool.input || '',
        output: tool.output || '',
        usedTools: [tool],
        timestamp: new Date().toISOString(),
      });
    });
  }

  if (flowiseData.sourceDocuments && Array.isArray(flowiseData.sourceDocuments)) {
    trace.push({
      agentName: 'Retrieval Agent',
      nodeName: '文档检索',
      input: flowiseData.question || '',
      output: `检索到 ${flowiseData.sourceDocuments.length} 个相关文档`,
      sourceDocuments: flowiseData.sourceDocuments,
      timestamp: new Date().toISOString(),
    });
  }

  // 如果没有找到具体的追踪信息，创建一个通用的步骤
  if (trace.length === 0) {
    trace.push({
      agentName: 'Flowise Agent',
      nodeName: '问答处理',
      input: flowiseData.question || '',
      output: flowiseData.answer || flowiseData.text || '',
      timestamp: new Date().toISOString(),
    });
  }

  return trace;
}

// 导出带 CORS 支持的处理器
export const POST = withCors(handlePOST);

// 处理 OPTIONS 预检请求
export async function OPTIONS(request: NextRequest) {
  const origin = request.headers.get('origin');
  const response = new NextResponse(null, { status: 200 });
  
  if (origin && ['http://localhost:3000', 'http://localhost:3001', 'http://localhost:3002'].includes(origin)) {
    response.headers.set('Access-Control-Allow-Origin', origin);
  }
  response.headers.set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
  response.headers.set('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-Requested-With, Accept, Origin');
  response.headers.set('Access-Control-Allow-Credentials', 'true');
  response.headers.set('Access-Control-Max-Age', '86400');
  
  return response;
}
